package com.zx.flow.api.config;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.zx.flow.api.dict.FlowDict.Event;
import com.zx.flow.api.util.GroovyScriptUtil;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import lombok.Data;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

@Data
public class FlowConfig {

    /**
     * 流程id,自动生成，全局唯一
     */
    private String id;

    /**
     * 流程编号，自定义
     */
    private String flowCode;

    /**
     * 流程名称，自定义
     */
    private String flowName;

    /**
     * 流程节点
     */
    private List<FlowConfigNode> nodes;

    /**
     * 【无需设置】是否开启
     */
    private Boolean enable;

    /**
     * 【无需设置】版本
     */
    private Integer version;

    private Date createTime;

    private Date updateTime;

    /**
     * 归属的安全账号
     */
    private String secretId;

    @JsonIgnore
    public FlowConfigNode getStartNode() {
        for (FlowConfigNode node : this.nodes) {
            if (node.isStart()) {
                return node;
            }
        }
        return null;
    }

    @JsonIgnore
    public FlowConfigNode getEndNode() {
        for (FlowConfigNode node : this.nodes) {
            if (node.isEnd()) {
                return node;
            }
        }
        return null;
    }

    @JsonIgnore
    public boolean isEnd(String nodeCode) {
        return getNode(nodeCode).isEnd();
    }

    @JsonIgnore
    public boolean isStart(String nodeCode) {
        return getNode(nodeCode).isStart();
    }

    @JsonIgnore
    public FlowConfigNode getNode(String nodeCode) {
        for (FlowConfigNode node : this.nodes) {
            if (Objects.equals(node.getCode(), nodeCode)) {
                return node;
            }
        }
        return null;
    }

    @JsonIgnore
    public FlowConfigNode getToConfig(String nodeCode, Event event, String extendData) {
        FlowConfigNode node = this.getNode(nodeCode);
        // 当前node的action
        FlowConfigAction action = node == null ? null : this.getAction(node, event);
        // 下一个节点的code
        FlowConfigToNode toNode = action == null ? null : getTo(action, extendData);
        // 下一个节点的config
        return toNode == null ? null : getNode(toNode.getCode());
    }

    @JsonIgnore
    public FlowConfigAction getAction(FlowConfigNode configNode, Event event) {
        List<FlowConfigAction> actions = configNode.getAction();
        if (CollectionUtils.isEmpty(actions)) {
            return null;
        }
        // 只有一个去向，直接返回
        if (actions.size() == 1) {
            return actions.get(0);
        }
        // 对比event
        for (FlowConfigAction action : actions) {
            if (Objects.equals(event.getCode(), action.getEvent())) {
                return action;
            }
        }
        // 实在没有，返回第一个没有配置事件的action
        for (FlowConfigAction action : actions) {
            if (StringUtils.isEmpty(action.getEvent())) {
                return action;
            }
        }
        return null;
    }

    @JsonIgnore
    public FlowConfigToNode getTo(FlowConfigAction actionConfig, String extendData) {
        List<FlowConfigToNode> tos = actionConfig.getTo();
        if (CollectionUtils.isEmpty(tos)) {
            return null;
        }
        // 只有一个去向，直接返回
        if (tos.size() == 1) {
            return tos.get(0);
        }
        // 有多个，则逐条执行conditio，直到找到符合的
        for (FlowConfigToNode to : tos) {
            // 没有条件，则直接返回
            try {
                if (StringUtils.isEmpty(to.getCondition())
                        || GroovyScriptUtil.conditionAction(to.getCondition(), extendData)) {
                    return to;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }


}
